#!/usr/local/bin/perl -w

use strict;

use App::Options (
    options => [qw(dbdriver dbclass dbhost dbname dbuser dbpass)],
    option => {
        dbclass  => { default => "App::Repository::MySQL", },
        dbdriver => { default => "mysql", },
        dbhost   => { default => "localhost", },
        dbname   => { default => "test", },
        dbuser   => { default => "", },
        dbpass   => { default => "", },
    },
);

use Test::More qw(no_plan);
use lib "../App-Context/lib";
use lib "../../App-Context/lib";
use lib "lib";
use lib "../lib";
use lib ".";
use lib "t";

if (!$App::options{dbuser}) {
    ok(1, "No dbuser given. Tests assumed OK. (add dbuser=xxx and dbpass=yyy to app.conf in 't' directory)");
    exit(0);
}

BEGIN {
   use_ok("App");
}
use RepositoryTestUtils qw(create_table_test_app_cache drop_table_test_app_cache);

my $context = App->context(
    %App::options,
    conf_file => "",
    conf => {
        Repository => {
            default => {
                class => $App::options{dbclass},
                dbdriver => $App::options{dbdriver},
                dbhost => $App::options{dbhost},
                dbname => $App::options{dbname},
                dbuser => $App::options{dbuser},
                dbpass => $App::options{dbpass},
                table => {
                    test_person => {
                        primary_key => ["person_id"],
                        column => {
                            data => {
                                dbexpr => "ifnull(uncompress(data),data)",
                                dbexpr_update => "compress(%s)",
                            },
                        },
                    },
                },
            },
        },
        SharedDatastore => {
            default => {
                class                     => "App::SharedDatastore::Repository",
                compress                  => 1,
                repository                => "default",
                table                     => "test_app_cache",
                cache_type                => "dbquery",
                cache_type_column         => "cache_type",
                cache_key_column          => "cache_key",
                data_column               => "data",
                generate_dttm_column      => "generate_dttm",
                serializer_column         => "serializer",
                serialization_args_column => "serialization_args",
            },
        },
    },
    debug_sql => $App::options{debug_sql},
    trace => $App::options{trace},
);

my $rep = $context->repository();
&drop_table_test_app_cache($rep);
&create_table_test_app_cache($rep);

{
    my ($sds, $key, $value, $keyref, $valueref, $valueref2, $hashkey, $serialized_value);

    foreach my $name ("default") {
        $sds = $context->service("SharedDatastore", $name);
        ok(defined $sds, "[$name] constructor ok");

        isa_ok($sds, "App::SharedDatastore", "[$name] right class");
        is($sds->service_type(), "SharedDatastore", "[$name] right service type");

        my $dump = $sds->dump();
        ok($dump =~ /^\$SharedDatastore__$name = /, "[$name] dump");
        $sds->set("pi", 3.1416);
        $value = $sds->get("pi");
        is($value, 3.1416, "[$name] set()/get() works (for pi=$value)");

        $keyref = [ "person",
            { "age.ge" => 21, last_name => "Adkins" },
            [ "person_id", "last_name", "first_name", "age", "eye_color" ],
            { numrows => 20, cache => {}, },
        ];
        $valueref = [
            [ 1, "Adkins", "Stephen",        40, "Blue",  ],
            [ 2, "Adkins", "Susan (Little)", 40, "Brown", ],
            [ 3, "Adkins", "Bill",           43, "Brown", ],
            [ 4, "Adkins", "Susan",          44, "Brown", ],
            [ 5, "Adkins", "Marybeth",       47, "Blue",  ],
        ];

        $sds->set_ref($keyref, $valueref);
        $valueref2 = $sds->get_ref($keyref);
        is_deeply($valueref, $valueref2, "[$name] set_ref()/get_ref() works");
        
        $hashkey = $sds->hashkey($keyref);
        $valueref2 = $sds->get_ref($hashkey);
        is_deeply($valueref, $valueref2, "[$name] set_ref()/get_ref(hashkey) works (hashkey=$hashkey)");
        
        $serialized_value = $sds->serialize($valueref);
        $value = $sds->get($hashkey);
        is($value, $serialized_value, "[$name] set_ref()/get(hashkey) works");
        
        $valueref2 = $sds->deserialize($serialized_value);
        is_deeply($valueref, $valueref2, "[$name] serialize()/deserialize() works");
        
        $value = $sds->get("foo");
        is($value, undef, "[$name] get(foo) is undef");
        
        $valueref2 = $sds->get_ref("foo");
        is($valueref2, undef, "[$name] get_ref(foo) is undef");
        
        $sds->set_ref("foo", undef);
        $value = $sds->get_ref("foo");
        is($value, undef, "[$name] get_ref(foo) is undef after set to undef");
    }
}

&drop_table_test_app_cache($rep);

exit 0;

